package com.xxmw.transaction.service.app.component;

import com.alibaba.fastjson.JSONObject;
import com.xxmw.transaction.enumeration.BourseEnum;
import com.xxmw.transaction.model.app.BoursePrice;
import com.xxmw.transaction.model.app.Symbol;
import com.xxmw.transaction.service.app.SymbolService;
import com.xxmw.transaction.service.support.AbstractWebSocketAdapter;
import com.xxmw.transaction.service.support.SymbolSubWebSocket;
import lombok.extern.slf4j.Slf4j;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft;
import org.java_websocket.drafts.Draft_6455;
import org.java_websocket.handshake.ServerHandshake;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.net.URI;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 中币websocket相关接口
 */
@Slf4j
@Component(value = "zBApplication")
public final class ZBApplication  extends AbstractWebSocketAdapter implements SymbolSubWebSocket {

    /**
     * webSocket基础接口
     */
    private static final String wb_url = "wss://api.zb.live/websocket";

    private static final String EVENT = "event";

    private static final String EVENT_VALUE = "addChannel";

    private static final String CHANNEL = "channel";

    private static final String CHANNET_VALUE = "_ticker";

    private long period = 3000;

    @Autowired
    private SymbolService symbolService;

    @Override
    public BoursePrice getSymbolPrice(String symbol) {
        return symbol_map.get(symbol);
    }

    @Override
    public void cleanSymbolPrice(String symbol) {
    	symbol_map.remove(symbol);
    }

    @Override
    public void subscribe(Symbol symbol) {
        JSONObject object = new JSONObject();
        object.put(EVENT, EVENT_VALUE);
        object.put(CHANNEL,symbol.getName()+CHANNET_VALUE);
        client.send(object.toJSONString());
    }

    @Override
    public void unSubscribe(Symbol symbol) {

    }

    @Override
    public void subscribeList(Set<Symbol> subSet) {
        for (Symbol symbol:
             subSet) {
            subscribe(symbol);
        }
    }

    @Override
    public void destroy() throws Exception {
        this.client.close();
        scheduled.shutdown();
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        super.afterPropertiesSet(new ZBWebSocketClient(new URI(wb_url), new Draft_6455(), null, 5000));
        scheduled.scheduleWithFixedDelay(() -> heartBeat(), period, period, TimeUnit.MILLISECONDS);
    }

    public  class ZBWebSocketClient extends WebSocketClient {

        public ZBWebSocketClient(URI serverUri, Draft protocolDraft, Map<String, String> httpHeaders, int connectTimeout) {
            super(serverUri, protocolDraft, httpHeaders, connectTimeout);
        }

        @Override
        public void onOpen(ServerHandshake serverHandshake) {
            log.info("中币webSocket连接中...");
            Set<Symbol> subSet = symbolService.listByBourse(BourseEnum.ZB.getValue());
            if (subSet != null && !subSet.isEmpty()) {
                log.info("中币开始订阅");
                subscribeList(subSet);
            }
        }

        @Override
        public void onMessage(String s) {
            if (s.contains("data")) {
                JSONObject res = JSONObject.parseObject(s);
                String symbol = res.getString("channel");
                symbol = symbol.replace(CHANNET_VALUE, "");
                JSONObject data = res.getJSONObject("ticker");
//                log.info("中币收到{}买一价:{},卖一价:{}",symbol,data.getBigDecimal("buy"),data.getBigDecimal("sell"));
                BoursePrice price = BoursePrice.builder().buyPrice(data.getBigDecimal("buy")).sellPrice(data.getBigDecimal("sell")).updateTime(new Date()).data(res.toJSONString()).build();
                // log.info("中币获取到【***{}***】的实时价格为：{}", symbol, price.toString());
                symbol_map.put(symbol, price);
            }
        }

        @Override
        public void onClose(int i, String s, boolean b) {
            log.info("中币websocket断开连接");
        }

        @Override
        public void onError(Exception e) {
            log.error("中币连接错误:{}",e);
        }
    }
}
